home *** CD-ROM | disk | FTP | other *** search
/ Shareware Extravaganza - Disc 1 / ShareWare Extravaganza 1 of 4 (The Ultimate Shareware Company).iso / sblaster / lrgsnded.zip / LRGSNDED.C next >
C/C++ Source or Header  |  1990-06-01  |  13KB  |  497 lines

  1. /*============================================================================
  2.  * File     :   LRGSNDED.C                                                   *
  3.  * Title    :   Sound Editor for buffers larger than 64K                     *
  4.  *                                                                           *
  5.  * Author   :   Randall Smith, Dept. of Classics, UCSB                       *
  6.  * Project  :   COVOX Sound Digitizing                                       *
  7.  * System   :   Microsoft C 6.0                                              *
  8.  *              Microsoft Quick C 2.51                                       *
  9.  *                                                                           *
  10.  * Ver  DDMmmYY Name            Comment                                      *
  11.  * ---  ------- ----            -------                                      *
  12.  * 1.0  30May90 Randall Smith   Original version of SEDIT.C                  *
  13.  * 2.0  31May90 Randall Smith   Removed item editing to make general version *
  14.  * 2.1  01Jun90 Randall Smith   Cleaned up a few details and added keyboard  *
  15.  *                                                                           *
  16.  *                                                                           *
  17.  * Copyright (c) Randall M. Smith  1990                                      *
  18.  * ---------                                                                 *
  19.  * This source code may be used freely as long as its origin is acknowledged.*
  20.  *                                                                           *
  21.  *                                                                           *
  22.  * Summary                                                                   *
  23.  * -------                                                                   *
  24.  * This provides a sound file recording, viewing, and playback function.     *
  25.  * It requires a VGA and works best with a mouse.  It is currently hard wired*
  26.  * to use 4 blocks of 64000 bytes each and will crash if that much free RAM  *
  27.  * is not available.  It relies on the compiler correctly working with HUGE  *
  28.  * arrays, which the COVOX library routines were not designed for, so it may *
  29.  * not work in every type of system and memory configuration.                *
  30.  *                                                                           *
  31.  *==========================================================================*/
  32.  
  33. #include "snddefs.h"
  34. #include "say8.h"
  35. #include "rec8.h"
  36.  
  37. #define NUM_BUTTONS 7
  38. #define L_BUT   0
  39. #define PLAY    1
  40. #define ZOOM    2
  41. #define RECRD   3
  42. #define LOAD    4
  43. #define QUIT    5
  44. #define R_BUT   6
  45.  
  46. #define WIDTH   90
  47. #define BLK   64000
  48. #define BUFFSIZE  4 * BLK
  49.  
  50. #define RECORD_SIZE 256L
  51.  
  52. char *button_text[] = {
  53.     "< <== >",
  54.     "<play>",
  55.     "<zoom>",
  56.     "<recrd>",
  57.     " <load>",
  58.     "<quit>",
  59.     "< ==> >"
  60. };
  61.  
  62. int block, section;
  63. unsigned int    mpx;
  64. BOOL    zoom_flag, mse_flag;
  65. FILE    *out_fp;
  66. static long count = 0;
  67.  
  68.  
  69. main(int argc, char *argv[])
  70. {
  71.     int     stream, i;
  72.     int     rate, port_out, treble, ret;
  73.     unsigned int    segbuf, num_read, j;
  74.     unsigned int    num_to_write;
  75.     char    in_fname[_MAX_PATH], out_fname[_MAX_PATH], tmp_num[10], tmp_msg[80];
  76.     BYTE huge *temp_buffer = NULL;
  77.     BYTE huge *say_buffer = NULL;
  78.     long    filesize, size, templong, left_cursor, right_cursor;
  79.     BOOL    quit_flag;
  80.     BYTE    tmp_chr;
  81.  
  82. ret = check_mouse();        /* see if mouse is present, and if not do not try to use it */
  83. if (ret == NO_MOUSE) {
  84.     mse_flag = FALSE;
  85. }
  86. else {
  87.     mse_flag = TRUE;
  88. }
  89.  
  90. limit_cursor(HORIZ, 0, 640);    /* set cursor field to full VGA screen */
  91. limit_cursor(VERT, 0, 480);
  92.  
  93. /* set default conditions.  Change these for different systems. */
  94. rate = 132;
  95. port_out = 4;
  96. treble = 0;
  97. left_cursor = 0L;
  98. right_cursor = 64000L;
  99. mpx = 100;
  100.  
  101. out_fname[0] = '\0';
  102. in_fname[0] = '\0';
  103.  
  104. init_screen();
  105.  
  106. if( _dos_allocmem( (BUFFSIZE/16)+2, &segbuf ) ) {
  107.     get_string("Not enough memory for data.  Press any key...", tmp_msg);
  108.     reset_screen();
  109.     exit(-1);
  110. }
  111. FP_SEG( say_buffer ) = segbuf;
  112.  
  113. say_buffer += 16;   /* set say_buffer ahead of header */
  114. temp_buffer = say_buffer;
  115.  
  116. for (i=0; i<(BUFFSIZE/BLK); i++) {    /* set whole buffer to midline (128) */
  117.     for (j=0; j<BLK; j++) {
  118.         *(temp_buffer++) = '\x80';
  119.     }
  120. }
  121.  
  122. for (j=0; j<16; j++) {
  123.     *(temp_buffer++) = '\x80';
  124. }
  125.  
  126. block = 0;
  127. section = 0;
  128. quit_flag = FALSE;
  129. while (!quit_flag) {
  130.     draw_block(say_buffer);
  131.     ret = get_input(&left_cursor, &right_cursor);   /* get mouse or kbd input */
  132.     switch (ret) {
  133.  
  134.     case F1:
  135.     case PLAY:  temp_buffer = say_buffer + left_cursor;
  136.                 size = right_cursor - left_cursor;
  137.                 say8((void huge *) temp_buffer, size, rate, port_out, treble);
  138.                 break;
  139.  
  140.     case F2:        /* zoom from a pixel per 100 bytes to 1:1.  Zoom value could be changed. */
  141.     case ZOOM:  if (zoom_flag) {
  142.                     zoom_flag = FALSE;
  143.                     mpx = 100;
  144.                     section = 0;
  145.                 }
  146.                 else {
  147.                     zoom_flag = TRUE;
  148.                     mpx = 1;
  149.                     section = left_cursor/640;  /* start near left cursor position */
  150.                 }
  151.                 break;
  152.  
  153.     case F3:
  154.     case RECRD: temp_buffer = say_buffer;
  155.  
  156.                 for (i=0; i<(BUFFSIZE/64000); i++) {    /* clear buffer before recording */
  157.                     for (j=0; j<64000; j++) {
  158.                         *(temp_buffer++) = '\x80';
  159.                     }
  160.                 }
  161.                 for (j=0; j<16; j++) {
  162.                     *(temp_buffer++) = '\x80';
  163.                 }
  164.                 get_string("File to record: ", in_fname);
  165.                 get_string("Rate: ", tmp_num);
  166.                 rate = atoi(tmp_num);
  167.                 if (_dos_creat(in_fname, _A_NORMAL, &stream)) {
  168.                     sprintf(tmp_msg,"Could not open %s", in_fname);
  169.                     put_error(tmp_msg);
  170.                 }
  171.                 get_string("Press <ENTER> to begin recording, then any key to stop");
  172.                 temp_buffer = say_buffer - 16;
  173.                 filesize = record8((void huge *) temp_buffer, BUFFSIZE,
  174.                             rate,0);
  175.  
  176.                 if ( kbhit() )
  177.                     getch();    /* eat char from stopping record routine */
  178.                 while (filesize > 0) {
  179.                     if (filesize > 64000)
  180.                         num_to_write = 64000;
  181.                     else
  182.                         num_to_write = filesize;
  183.                     if (_dos_write(stream, (void far *)temp_buffer, num_to_write, &num_to_write)) {
  184.                         sprintf(tmp_msg,"Error writing to %s", in_fname);
  185.                         put_error(tmp_msg);
  186.  
  187.                     }
  188.                     filesize -= num_to_write;
  189.                     temp_buffer += num_to_write;
  190.  
  191.                 }
  192.                 _dos_close(stream);
  193.                 break;
  194.  
  195.     case F4:
  196.     case LOAD:  get_string("File to load: ", in_fname);
  197.                 if (_dos_open(in_fname, O_RDONLY, &stream)) {
  198.                     sprintf(tmp_msg,"Could not open %s", in_fname);
  199.                     put_error(tmp_msg);
  200.                 }
  201.                 temp_buffer = say_buffer - 16;
  202.  
  203.                 filesize = 0;
  204.                 for (i=0; i<(BUFFSIZE/64000); i++) {
  205.                     for (j=0; j<64000; j++)
  206.                         *(temp_buffer+j) = '\x80';  /* clear each block before data read in */
  207.  
  208.                     if (_dos_read(stream, (void far *)temp_buffer, 64000, &num_read)) {
  209.                         sprintf(tmp_msg,"Error reading %s", in_fname);
  210.                         put_error(tmp_msg);
  211.                     }
  212.                     filesize += num_read;
  213.                     temp_buffer += 64000;
  214.  
  215.                 }
  216.                 for (j=0; j<16; j++)
  217.                     *(temp_buffer+j) = '\x80';
  218.                 tmp_chr = *(say_buffer-7);  /* get rate of recording from header */
  219.                 rate = (int)tmp_chr;
  220.  
  221.                 temp_buffer = say_buffer;
  222.                 _dos_close(stream);
  223.  
  224.                 block = 0;
  225.                 section = 0;
  226.                 break;
  227.  
  228.     case PGUP:          /* go left one section or block */
  229.     case L_BUT: if (zoom_flag) {
  230.                     section--;
  231.                     if (section < 0) {
  232.                         if (block == 0) {
  233.                             section = 0;
  234.                         }
  235.                         else {
  236.                             block--;
  237.                             section = 99;
  238.                         }
  239.                     }
  240.                 }
  241.                 else {
  242.                     block--;
  243.                     if (block < 0) {
  244.                         block = 0;
  245.                     }
  246.                 }
  247.                 break;
  248.  
  249.     case PGDN:
  250.     case R_BUT: if (zoom_flag) {
  251.                     section++;
  252.                     if (section > 99) {
  253.                         if (block == 3)
  254.                             section = 99;
  255.                         else {
  256.                             block++;
  257.                             section = 0;
  258.                         }
  259.                     }
  260.                 }
  261.                 else {
  262.                     block++;
  263.                     if (block > 3)
  264.                         block = 3;
  265.                 }
  266.                 break;
  267.  
  268.     case ESC:
  269.     case QUIT:  quit_flag = TRUE;
  270.                 break;
  271.  
  272.     }  /* end switch */
  273. }  /* end main while loop */
  274.  
  275. fclose(out_fp);
  276. _dos_close(stream);
  277. _dos_freemem(segbuf);
  278. reset_screen();
  279.  
  280. }  /* end main */
  281.  
  282.  
  283. /*****************************************************************************
  284.  *  DRAW_BLOCK
  285.  *
  286.  *  This function draws one full screen of data, either 1:100 or 1:1 depending
  287.  *  on the value in mpx, which is determined by the state of zoom_flag.
  288.  *
  289.  *****************************************************************************/
  290.  
  291. draw_block(char huge *say_buffer)
  292. {
  293.     char huge *ptr;
  294.     int     i;
  295.  
  296.  
  297. _setcolor(0);
  298. _rectangle(_GFILLINTERIOR, 0, 20, 639, 299);    /* clear display area */
  299. _setcolor(7);
  300. _moveto(0, 147);    /* set position to middle point of left margin */
  301.  
  302. ptr = say_buffer + (block*64000) + (section*640);
  303.  
  304. for (i=0; i<640; i++) {
  305.     plot(i, (BYTE)*ptr);
  306.     ptr += mpx;
  307. }
  308.  
  309. }  /* end draw_block */
  310.  
  311.  
  312. /****************************************************************************
  313.  *  INIT_SCREEN
  314.  *
  315.  *  This function set the video mode and draws the basic screen.
  316.  *
  317.  ****************************************************************************/
  318.  
  319. init_screen()
  320. {
  321.     int     i;
  322.  
  323. _setvideomode(_VRES16COLOR);
  324. _remappalette(0, _WHITE);
  325. _remappalette(7, _BLACK);
  326. _settextcolor(7);
  327. _setcolor(7);
  328. _rectangle(_GBORDER, 0, 18, 639, 349);
  329. _moveto(0, 300);
  330. _lineto(639, 300);
  331.  
  332. for (i=0; i<NUM_BUTTONS; i++)
  333.     draw_button(i);
  334.  
  335. }  /* end init_screen */
  336.  
  337.  
  338.  
  339. /****************************************************************************
  340.  *  RESET_SCREEN
  341.  *
  342.  *  This function restores the video mode active when program started.
  343.  *
  344.  ****************************************************************************/
  345.  
  346. reset_screen()
  347. {
  348. _setvideomode(_DEFAULTMODE);
  349.  
  350. }  /* end reset_screen */
  351.  
  352.  
  353.  
  354. /****************************************************************************
  355.  *  GET_INPUT
  356.  *
  357.  *  This function gets either mouse or kbd input and returns either the
  358.  *  value of the screen button clicked or the ASCII value of the key pushed.
  359.  *  This routine also sets the left and right cursor, but only by mouse at
  360.  *  this time.  A keyboard equivalent should be added.
  361.  *
  362.  ****************************************************************************/
  363.  
  364. get_input(long *lc, long *rc)
  365. {
  366.     BOOL    quit_flag;
  367.     int     ret, x, y, ch;
  368.     long    r_curs, l_curs;
  369.     char    out_str[80];
  370.  
  371. l_curs = *lc;
  372. r_curs = *rc;
  373.  
  374. display_m_cursor(SHOW);
  375.  
  376. quit_flag = FALSE;
  377. while (!quit_flag) {
  378.  
  379.     sprintf(out_str, "Left: %7lu     Right: %7lu     Block: %d    Section: %3d", l_curs, r_curs, block, section);
  380.     _settextposition(1, 3);
  381.     _outtext(out_str);
  382.  
  383.         /* This peculiar construction is to keep from updating the status line
  384.          * every time a check for mouse or key is made. */
  385.  
  386.     if (mse_flag) {
  387.         while ( !(ret = check_position(&x, &y)) && (kbhit() == 0) );
  388.     }
  389.     else {
  390.         while (kbhit() == 0);
  391.     }
  392.     if (ret == RIGHT) {
  393.         if (y < 300)
  394.             r_curs = (long)(x*mpx) + (long)(block*64000L) + (long)(section*640);
  395.     }
  396.     else if (ret == LEFT) {
  397.             if (y < 300) {
  398.                 l_curs = (long)(x*mpx) + (long)(block*64000L) + (long)(section*640);
  399.             }
  400.             else if (y < 350) {
  401.                 ret = x/WIDTH;
  402.                 quit_flag = TRUE;
  403.             }
  404.         }
  405.     else {
  406.         ch = getch();
  407.         if (ch == '\0')
  408.            ch = getch();
  409.         ret = ch;
  410.         quit_flag = TRUE;
  411.     }
  412. }  /* end while loop */
  413.  
  414. display_m_cursor(HIDE);
  415.  
  416. *lc = l_curs;
  417. *rc = r_curs;
  418.  
  419. return(ret);
  420.  
  421. }   /* end get_input */
  422.  
  423.  
  424. /****************************************************************************
  425.  *  PLOT
  426.  *
  427.  *  This routine simply draws a line from the last point to the current point
  428.  *
  429.  ****************************************************************************/
  430.  
  431. plot(int ix, BYTE iy)
  432. {
  433.  
  434. _lineto(ix, (short)(275-iy));
  435.  
  436. }  /* end plot */
  437.  
  438.  
  439.  
  440. /****************************************************************************
  441.  * DRAW_BUTTON
  442.  *
  443.  * This function draws the buttons on the screen.
  444.  *
  445.  ****************************************************************************/
  446.  
  447. draw_button(int x_pos)
  448. {
  449.  
  450. display_m_cursor(HIDE);
  451. _settextposition(21, (x_pos*((WIDTH/8)+.5)+3));
  452. _outtext(button_text[x_pos]);
  453. display_m_cursor(SHOW);
  454.  
  455. }   /* end draw_button */
  456.  
  457.  
  458. /****************************************************************************
  459.  *  GET_STRING
  460.  *
  461.  *  This function prints a prompt on the screen under the buttons and gets
  462.  *  a string back from the user.
  463.  *
  464.  ****************************************************************************/
  465.  
  466. get_string(char *prompt, char *str)
  467. {
  468.  
  469. _setcolor(0);
  470. _rectangle(_GFILLINTERIOR, 0, 360, 639, 420);
  471. _setcolor(7);
  472. _settextposition(26, 2);
  473. _outtext(prompt);
  474. gets(str);
  475.  
  476. }  /* end get_string */
  477.  
  478.  
  479. /***************************************************************************
  480.  *  PUT_ERROR
  481.  *
  482.  *  Replacement for fprintf(stderr) in graphics mode.  Same as GET_STRING
  483.  *  but does not return a string.
  484.  *
  485.  ***************************************************************************/
  486.  
  487. put_error(char *msg)
  488. {
  489.  
  490. _setcolor(0);
  491. _rectangle(_GFILLINTERIOR, 0, 360, 639, 420);
  492. _setcolor(7);
  493. _settextposition(26, 2);
  494. _outtext(msg);
  495.  
  496. }  /* end put_error */
  497.